﻿using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Security.Principal;
using System.Windows.Forms;
using shfa.snomtastic.systray.forms;
using shfa.snomtastic.systray.components;
using System.Threading;

namespace shfa.snomtastic.systray
{

    public partial class MainApplication : ApplicationContext
    {

        #region Private Members

        private frmLogin frm;

        private System.Windows.Forms.Timer tmMain;
        private NotifyIcon niMain;

        private ContextMenuStrip cmMain = new ContextMenuStrip();
        private Icon[] icons;
        private Image[] MenuImages;

        private string userSID;
        private string userName;
        private DateTime lastCheck;

         


        #endregion

        #region Initialise

        public MainApplication()
        {
            InitImages();
            InitNotifyIcon();
            InitAbout();
            InitUser();
            InitTimer();
            InitToast();

            CheckUser(false);
        }

        private void InitImages()
        {

            // Tray Icons
            Assembly ass = Assembly.GetExecutingAssembly();
            Stream image = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.trayicon.bmp");
            Bitmap bmp = new Bitmap(image);
            bmp.MakeTransparent();
            icons = new Icon[3];
            for (int i = 0; i < icons.Length; i++)
            {
                Rectangle rect = new Rectangle((i) * 16, 0, 16, 16);
                icons[i] = Icon.FromHandle(bmp.Clone(rect, bmp.PixelFormat).GetHicon());
            }

            // Menu Images
            MenuImages = new Image[8];
            Stream imgPass = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.pass.png");
            Stream imgUser = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.user.png");
            Stream imgBoot = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.boot.png");
            Stream imgInfo = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.info.png");
            Stream imgExit = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.exit.png");
            Stream imgPopN = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.never.png");
            Stream imgPopB = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.busy.png");
            Stream imgPopA = ass.GetManifestResourceStream("shfa.snomtastic.systray.images.always.png");


            MenuImages[0] = new Bitmap(imgPass);
            MenuImages[1] = new Bitmap(imgUser);
            MenuImages[2] = new Bitmap(imgBoot);
            MenuImages[3] = new Bitmap(imgInfo);
            MenuImages[4] = new Bitmap(imgExit);
            MenuImages[5] = new Bitmap(imgPopN); // Never = Green
            MenuImages[6] = new Bitmap(imgPopA); // Always = Red
            MenuImages[7] = new Bitmap(imgPopB); // Busy = Orange


        }

        private void InitNotifyIcon()
        {
            RegSettings rs = new RegSettings();

            int iCommToast = (int)rs.hideCommunicatorToastMode();
            int iSnomToast = (int)rs.hideSnomtasticToastMode();

            // menu


            ToolStripMenuItem ddCommunicatorToast = new ToolStripMenuItem("Communicator Pop Up", MenuImages[iCommToast + 5]);
            ToolStripMenuItem ddSnomtasticToast = new ToolStripMenuItem("Snomtastic Pop Up", MenuImages[iSnomToast + 5]);

            ddCommunicatorToast.Name = "ddCommunicatorToast";
            ddSnomtasticToast.Name = "ddSnomtasticToast";

            ddCommunicatorToast.Enabled = !rs.hideCommunicatorToastDisabled();
            ddSnomtasticToast.Enabled = !rs.hideSnomtasticToastDisabled();

            ddCommunicatorToast.DropDownItemClicked += new ToolStripItemClickedEventHandler(ddCommunicatorToast_DropDownItemClicked);
            ddSnomtasticToast.DropDownItemClicked += new ToolStripItemClickedEventHandler(ddSnomtasticToast_DropDownItemClicked);

            ddCommunicatorToast.DropDownItems.AddRange(
                new ToolStripItem[] 
                { 
                    new ToolStripMenuItem("Show Always", MenuImages[5]) { Name="Never" }, 
                    new ToolStripMenuItem("Hide Always", MenuImages[6]) { Name="Always" },
                    new ToolStripMenuItem("Hide When Busy", MenuImages[7]) { Name="Busy" } 
                });

            ddSnomtasticToast.DropDownItems.AddRange(
                new ToolStripItem[] 
                { 
                    new ToolStripMenuItem("Show Always", MenuImages[5]) { Name="Never" }, 
                    new ToolStripMenuItem("Hide Always", MenuImages[6]) { Name="Always" },
                    new ToolStripMenuItem("Hide When Busy", MenuImages[7]) { Name="Busy" } 
                });

            cmMain.Items.AddRange(
                new ToolStripItem[]
                {
                   
                    new ToolStripMenuItem("Check Password", MenuImages[0], miPass_Click),
                    new ToolStripMenuItem("Re-register Phone", MenuImages[1], miUser_Click),
                    new ToolStripMenuItem("Reboot Phone", MenuImages[2], miBoot_Click),
                    new ToolStripSeparator(),
                    ddCommunicatorToast,
                    ddSnomtasticToast,
                    new ToolStripSeparator(),
                    new ToolStripMenuItem("About", MenuImages[3], miInfo_Click),
                    new ToolStripMenuItem("Exit", MenuImages[4], miExit_Click)
                });



            // Icon
            niMain = new NotifyIcon();
            niMain.Icon = icons[0];
            niMain.Visible = true;

            niMain.ContextMenuStrip = cmMain;
            niMain.MouseDoubleClick += new MouseEventHandler(niMain_MouseDoubleClick);
          
        }

      
        void ddCommunicatorToast_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            HideToastInfo.HideToastModeType mode = ChangeToastMode("ddCommunicatorToast", e.ClickedItem.Name);
            RegSettings rs = new RegSettings();
            rs.setHideCommunicatorToastMode(mode);
        }

        void ddSnomtasticToast_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            HideToastInfo.HideToastModeType mode = ChangeToastMode("ddSnomtasticToast", e.ClickedItem.Name);
            RegSettings rs = new RegSettings();
            rs.setHideSnomtasticToastMode(mode);

        }




        void InitUser()
        {
            SetUserInfo();
        }

        private void InitTimer()
        {
            RegSettings rs = new RegSettings();

            tmMain = new System.Windows.Forms.Timer();
            tmMain.Interval = rs.ValidateInterval();
            tmMain.Tick += new EventHandler(tmMain_Tick);
            tmMain.Start();

        }

        #endregion

        #region Events

        protected void tmMain_Tick(object sender, EventArgs e)
        {
            RegSettings rs = new RegSettings();

            CheckUser(false);
            if (userPhone == null)
                InitToast();


            if (rs.ValidateInterval() != tmMain.Interval)
                tmMain.Interval = rs.ValidateInterval();

        }

        protected void niMain_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //niMain.BalloonTipText = "Username: " + userName + "\n" + "Last Check: " + lastCheck.ToShortTimeString();
            //niMain.ShowBalloonTip(5);
            showAbout();
        }

      


        protected void miPass_Click(object sender, EventArgs e)
        {
            CheckUser(true);
        }

        protected void miUser_Click(object sender, EventArgs e)
        {
            SendPhoneCommand(UserService.CommandType.Reregister);
        }

        protected void miBoot_Click(object sender, EventArgs e)
        {
            SendPhoneCommand(UserService.CommandType.Reboot);
        }

        protected void miInfo_Click(object sender, EventArgs e)
        {
           this.showAbout();
        }

        protected void miExit_Click(object sender, EventArgs e)
        {
            ExitThread();
            niMain.Visible = false;
            niMain.Dispose();
        }


        protected void frm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            tmMain.Start();
        }

        #endregion

        #region User

        private void CheckUser(bool bAlert)
        {
            this.niMain.Icon = icons[1];
            try
            {
                SetUserInfo();
                int iUpdate = NeedUpdate();
                switch (iUpdate)
                {
                    case -1:
                        if (bAlert)
                        {
                            MessageBox.Show("Service Unavailable.", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                        }
                        this.niMain.Icon = icons[2];
                        break;
                    case 0:
                        if (bAlert)
                        {
                            MessageBox.Show("Password is up to date.", "Check password", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                        }
                        System.Threading.Thread.Sleep(1000);
                        this.niMain.Icon = icons[0];
                        break;
                    case 1:
                        showForm("Password Changed", "Your desk phone needs to confirm its credentials. This may occur because you've changed your password, the OCS server was unavailable, or due to network issues. Your phone will restart after you update your password, which will interrupt any calls you may have in progress.");
                        this.niMain.Icon = icons[0];
                        break;
                    default:
                        break;
                }
            }
            catch
            {
                this.niMain.Icon = icons[2];
            }

            lastCheck = DateTime.Now;
        }

        private int NeedUpdate()
        {
            try
            {
                UserService.user RemoteUserService = new ClientUserService();
                if (RemoteUserService.NeedPasswordUpdate(userSID))
                    return 1;
            }
            catch
            {
                return -1;
            }
            return 0;
        }

        private void SetUserInfo()
        {
            if (WindowsIdentity.GetCurrent() != null)
            {
                userName = WindowsIdentity.GetCurrent().Name;
                userSID = WindowsIdentity.GetCurrent().User.ToString();
            }
        }

        #endregion

        #region Helpers


        private HideToastInfo.HideToastModeType ChangeToastMode(string sMenuItemName, string sModeName)
        {

            HideToastInfo.HideToastModeType mode;

            switch (sModeName)
            {
                case "Busy":
                    mode = HideToastInfo.HideToastModeType.Busy;
                    break;
                case "Always":
                    mode = HideToastInfo.HideToastModeType.Always;
                    break;
                default:
                    mode = HideToastInfo.HideToastModeType.Never;
                    break;
            }


            ToolStripItem[] tsi = cmMain.Items.Find(sMenuItemName, false);
            if (tsi != null && tsi[0] != null)
                ((ToolStripMenuItem)tsi[0]).Image = MenuImages[(int)mode + 5];


            return mode;
        }

        private void showForm(string headerText, string messageText)
        {
            tmMain.Stop();
            frm = new frmLogin();
            frm.Closing += new System.ComponentModel.CancelEventHandler(frm_Closing);

            frm.SetDisplay(headerText, messageText, userName, userSID);
            frm.ShowDialog();
        }

        private void SendPhoneCommand(UserService.CommandType cmd)
        {
            try
            {
                UserService.user RemoteUserService = new ClientUserService();
                RemoteUserService.SendPhoneCommand(userPhone.PhoneIp, cmd);
            }
            catch
            {
                // Error sending command to phone
            }
        }


        #endregion

    }
}
